﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;

namespace pyTivoMetadataManager
{
    [AttributeUsage(AttributeTargets.Field, AllowMultiple=false, Inherited=false)]
    public class DisplayNameAttribute : Attribute
    {
        private string _displayName = string.Empty;
        public string DisplayName
        {
            get { return (_displayName); }
            set { _displayName = value; }
        }

        public DisplayNameAttribute(string displayName)
        {
            DisplayName = displayName;
        }

        public static DisplayNameAttribute GetAttributeForValue(object value)
        {
            Type type = value.GetType();
            if (!Enum.IsDefined(type, value))
            {
                return (new DisplayNameAttribute("Unknown"));
            }
            string fieldName = Enum.GetName(type, value);
            return(GetAttributeForNamedField(type, fieldName));
        }

        public static Dictionary<string, string> GetLookupStructure(Type type)
        {
            Dictionary<string, string> values = new Dictionary<string, string>();
            FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Static);
            foreach (FieldInfo field in fields)
            {
                values.Add(GetAttributeForField(field).DisplayName, field.GetValue(null).ToString());
            }
            PropertyInfo[] props = type.GetProperties(BindingFlags.Public | BindingFlags.Static);
            foreach (PropertyInfo prop in props)
            {
                values.Add(GetAttributeForProperty(prop).DisplayName, prop.GetValue(null, null).ToString());
            }
            return (values);
        }

        public static Dictionary<string, T> GetLookupStructure<T>()
        {
            Type type = typeof(T);
            Dictionary<string, T> values = new Dictionary<string, T>();
            FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Static);
            foreach (FieldInfo field in fields)
            {
                values.Add(GetAttributeForField(field).DisplayName, (T)field.GetValue(null));
            }
            PropertyInfo[] props = type.GetProperties(BindingFlags.Public | BindingFlags.Static);
            foreach (PropertyInfo prop in props)
            {
                values.Add(GetAttributeForProperty(prop).DisplayName, (T)prop.GetValue(null, null));
            }
            return (values);
        }

        private static DisplayNameAttribute GetAttributeForNamedField(Type type, string fieldName)
        {
            FieldInfo field = type.GetField(fieldName);
            return (GetAttributeForField(field));
        }

        private static DisplayNameAttribute GetAttributeForField(FieldInfo field)
        {
            DisplayNameAttribute[] attrs = (DisplayNameAttribute[])field.GetCustomAttributes(typeof(DisplayNameAttribute), false);
            return (attrs.Length > 0 ? attrs[0] : new DisplayNameAttribute(field.Name));
        }

        private static DisplayNameAttribute GetAttributeForProperty(PropertyInfo prop)
        {
            DisplayNameAttribute[] attrs = (DisplayNameAttribute[])prop.GetCustomAttributes(typeof(DisplayNameAttribute), false);
            return (attrs.Length > 0 ? attrs[0] : new DisplayNameAttribute(prop.Name));
        }
    }
}
